package com.nq.service.impl;

/**

 * 开发者----股牛网络

 * 联系TG：gncms

 */
/**
 * 开发者----股牛网络
 * 联系TG：gncms
 */
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.nq.common.ServerResponse;
import com.nq.dao.*;
import com.nq.pojo.*;
import com.nq.pojo.vo.FundsApplyVo;
import com.nq.service.*;
import com.nq.utils.*;
import com.nq.utils.redis.CookieUtils;
import com.nq.utils.redis.JsonUtil;
import com.nq.utils.redis.RedisShardedPoolUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 配资申请
 * @author lr
 * @date 2020/07/24
 */
@Service("IFundsApplyService")
public class FundsApplyServiceImpl implements IFundsApplyService {
    private static final Logger log = LoggerFactory.getLogger(FundsApplyServiceImpl.class);

    @Resource
    private FundsApplyMapper fundsApplyMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    UserCashDetailMapper userCashDetailMapper;
    @Autowired
    FundsTradingAccountMapper fundsTradingAccountMapper;

    @Autowired
    IUserService iUserService;
    @Autowired
    IFundsSettingService iFundsSettingService;

    @Autowired
    private IStUserLevelService stUserLevelService;

    @Autowired
    private ISiteSettingService siteSettingService;

    @Autowired
    private FundsLeverMapper fundsLeverMapper;

    @Autowired
    private StAllocationSettingMapper stAllocationSettingMapper;


    @Transactional
    public ServerResponse insert(String lever, String margin, HttpServletRequest request) throws Exception {
        int ret = 0;
        if (StringUtils.isBlank(lever)) {
            return ServerResponse.createBySuccessMsg("Parameter error[lever)]");
        }

        User user = this.iUserService.getCurrentRefreshUser(request);
        if(user == null){
            return ServerResponse.createBySuccessMsg("Please log in and do it.");
        }


        // 申请一个未完成审核，不可以提交下一个
        QueryWrapper<FundsApply> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", user.getId());
        queryWrapper.eq("status", FundsApply.STATUS_0);
        List<FundsApply> applyList = fundsApplyMapper.selectList(queryWrapper);
        if (!applyList.isEmpty()) {
            return ServerResponse.createByErrorMsg("您上次的融资申请正在等待审核，审核成功后可以继续申请!");
        }

        // 计算配资金额  保证金乘以杠杆
        BigDecimal marginBig = new BigDecimal(margin);
        BigDecimal leverBig = new BigDecimal(lever);
        // 配资金额
        BigDecimal fundsAmount = marginBig.multiply(leverBig);

        // 判断门槛
        AtomicReference<StAllocationSetting> setting = new AtomicReference<>(new StAllocationSetting());
        List<StAllocationSetting> settingList = stAllocationSettingMapper.selectList(null);
        settingList.forEach(set -> {
            // 前开后闭
            if (fundsAmount.compareTo(set.getLow()) > 0 && fundsAmount.compareTo(set.getHigh()) <= 0) {
                setting.set(set);
            }
        });

        if (null == setting) {
            return ServerResponse.createByErrorMsg("No configuration data found.");
        }

        // 获取用户等级
        Integer levelByUserId = stUserLevelService.getUserLevelByUserId(user.getId());
        // 如果 VIP 等级小于配置的申请等级，则不允许申请
        if (levelByUserId.intValue() < setting.get().getLevel().intValue()) {
            return ServerResponse.createByErrorMsg("Only JVIP level " + setting.get().getLevel() + " or above can apply for funding allocation.");
        }

        // 判断申请次数
        QueryWrapper<FundsApply> query = new QueryWrapper<>();
        query.eq("user_id", user.getId());
        query.in("status", FundsApply.STATUS_1, FundsApply.STATUS_4); // 成功｜已结束
        query.between("add_time", DateUtils.getFirstDay(), DateUtils.getLastDay());
        List<FundsApply> applyBuSuccessList = fundsApplyMapper.selectList(query);
        if (CollectionUtils.isNotEmpty(applyBuSuccessList) && applyBuSuccessList.size() >= setting.get().getNumber().intValue()) {
            return ServerResponse.createByErrorMsg("You can't borrow more than " + setting.get().getNumber() + " a month.");
        }

        FundsApply model = new FundsApply();
        model.setUserId(user.getId());
        model.setUserName(user.getRealName());
        model.setUserPhone(user.getPhone());

        model.setFundsAmount(fundsAmount);
        model.setMargin(marginBig);
        model.setLever(leverBig.intValue());

        // 计算总操盘金额
        BigDecimal totalTradingAmount = marginBig.add(fundsAmount);
        model.setTotalTradingAmount(totalTradingAmount);
        // 日利率
//        BigDecimal manageRateBig = setting.get().getRate();
        // 管理费 fundsAmount  配资金额  乘以  selManageRate 管理费率
//        BigDecimal manageFee = fundsAmount.multiply(manageRateBig);
//        model.setManageFee(manageFee);

        // 默认按天配置
        model.setFundsType(1);
        // 可用资金金额
        BigDecimal user_enable_amt = user.getEnableAmt();

        //支付金额 = 保证金 + 管理费
        BigDecimal pay_amount = marginBig;
        int compareUserAmtInt = user_enable_amt.compareTo(pay_amount);
        log.info("用户可用金额 = {}  实际购买金额 =  {} 比较结果 = {} ", user_enable_amt, pay_amount, compareUserAmtInt);
        if (compareUserAmtInt == -1) {
            return ServerResponse.createByErrorMsg("The application failed, and the credit is less than " + pay_amount + " USD");
        }

        //自动生成订单编号
        model.setOrderNumber(KeyUtils.getUniqueKey());
        model.setPayAmount(pay_amount);
        ret = fundsApplyMapper.insert(model);

        if(ret > 0){
            //修改用户可用余额 = 当前余额 -支付金额
            BigDecimal reckon_enable = user_enable_amt.subtract(pay_amount);
            user.setEnableAmt(reckon_enable);
            int updateUserCount = this.userMapper.updateByPrimaryKeySelective(user);

            if (updateUserCount > 0) {
                log.info("【用户交易下单】修改用户金额成功");
                UserCashDetail ucd = new UserCashDetail();
                ucd.setPositionId(model.getId());
                ucd.setAgentId(user.getAgentId());
                ucd.setAgentName(user.getAgentName());
                ucd.setUserId(user.getId());
                ucd.setUserName(user.getRealName());
                ucd.setDeType("Allocation is frozen");
                ucd.setDeAmt(model.getPayAmount().multiply(new BigDecimal("-1")));
                ucd.setDeSummary("Apply for a day-by-day allocation:" + model.getOrderNumber()
                        + "，Block Amount：" + model.getPayAmount().multiply(new BigDecimal("-1")) );
                ucd.setAddTime(new Date());
                ucd.setIsRead(Integer.valueOf(0));
                int insertSxfCount = this.userCashDetailMapper.insert(ucd);
                if (insertSxfCount > 0) {
                    log.info("【按天配资】申请成功");
                }

            } else {
                log.error("【按天配资】修改用户金额出错");
                throw new Exception("[Assement by Day] Error in modifying the user amount");
            }
            return ServerResponse.createBySuccessMsg("Successful application！");
        } else {
            return ServerResponse.createBySuccessMsg("The application failed. Please try again later.！");
        }
    }

    @Override
    @Transactional
    public ServerResponse addFundsApplyByDays(Integer days, String margin, HttpServletRequest request) {
        if (null == days) {
            return ServerResponse.createBySuccessMsg("参数错误[days)]");
        }

        User user = this.iUserService.getCurrentRefreshUser(request);
        if(user == null){
            return ServerResponse.createBySuccessMsg("请登录并执行.");
        }

        // 申请一个未完成审核，不可以提交下一个
        QueryWrapper<FundsApply> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", user.getId());
        queryWrapper.eq("status", FundsApply.STATUS_0);
        List<FundsApply> applyList = fundsApplyMapper.selectList(queryWrapper);
        if (!applyList.isEmpty()) {
            return ServerResponse.createByErrorMsg("您上次的融资申请正在等待审核，审核成功后可以继续申请!");
        }


        FundsApply model = new FundsApply();
        model.setUserId(user.getId());
        model.setUserName(user.getRealName());
        model.setUserPhone(user.getPhone());


        BigDecimal fundsAmount = new BigDecimal(margin);
        model.setFundsAmount(fundsAmount);
        model.setMargin(BigDecimal.ZERO);
        model.setLever(1);

        // 计算总操盘金额
        BigDecimal totalTradingAmount = fundsAmount;
        model.setTotalTradingAmount(totalTradingAmount);

        // 目前印度版是无需管理费，只有超过配资时间后，需要缴纳2%的滞纳金
        BigDecimal manageRateBig = new BigDecimal(BigInteger.ZERO);
        model.setManageFee(manageRateBig);

        // 默认按天配置
        model.setFundsType(1);
        // 根据天数设置开始时间和结束时间
        model.setBeginTime(new Date());
        DateTime endTime = DateUtil.offsetDay(new Date(), days);
        model.setEndTime(endTime);
        model.setTradersCycle(days);
        //自动生成订单编号
        model.setOrderNumber(KeyUtils.getUniqueKey());
        model.setPayAmount(BigDecimal.ZERO);
        int ret = fundsApplyMapper.insert(model);
        if(ret > 0){
                log.info("【用户交易下单】修改用户金额成功");
                UserCashDetail ucd = new UserCashDetail();
                ucd.setPositionId(model.getId());
                ucd.setAgentId(user.getAgentId());
                ucd.setAgentName(user.getAgentName());
                ucd.setUserId(user.getId());
                ucd.setUserName(user.getRealName());
                ucd.setDeType("分配已冻结");
                ucd.setDeAmt(model.getPayAmount().multiply(new BigDecimal("-1")));
                ucd.setDeSummary("申请按天配资：" + model.getOrderNumber() + "，冻结金额：" + model.getPayAmount().multiply(new BigDecimal("-1")) );                ucd.setAddTime(new Date());
                ucd.setIsRead(Integer.valueOf(0));
                int insertSxfCount = this.userCashDetailMapper.insert(ucd);
                if (insertSxfCount > 0) {
                    log.info("【按天配资】申请成功");
                }
            return ServerResponse.createBySuccessMsg("申请成功！");
        } else {
            return ServerResponse.createBySuccessMsg("申请失败，请稍后再试！");
        }
    }
    /**
     * 补充保证金
     * @param applyId
     * @param amount
     * @param request
     * @return
     */
    @Override
    public ServerResponse supplyMargin(Integer applyId, BigDecimal amount, String payPwd, HttpServletRequest request) {
        User user = this.iUserService.getCurrentRefreshUser(request);
        if(user == null){
            return ServerResponse.createBySuccessMsg("Please log in and do it.");
        }

        // 校验支付密码
        String userPayPwd = user.getPayPwd();
        if (StringUtils.isBlank(userPayPwd)) {
            return ServerResponse.createByErrorMsg("You have not set a payment password yet. Please set a payment password before making a purchase!");
        }

        // 校验密码是否正确
        if (!SymmetricCryptoUtil.encryptPassword(payPwd).equals(userPayPwd)) {
            boolean isLocked = iUserService.isLocked(User.SUPPLY_MARGIN_PWD_PREFIX, user.getId());
            if (isLocked) {
                return ServerResponse.createByErrorMsg("Purchase failed, The password has exceeded 5 times. Please wait for half an hour before making a purchase.");
            }
            return ServerResponse.createByErrorMsg("Purchase failed, The password you entered is incorrect, please re-enter it!");
        }

        // 判断用户可用余额是否充足
        BigDecimal enableAmt = user.getEnableAmt();
        if (enableAmt.compareTo(amount) < 0) {
            return ServerResponse.createBySuccessMsg("Insufficient available balance, please recharge.");
        }
        // 增加配资申请的保证金
        FundsApply apply = fundsApplyMapper.selectById(applyId);
        if (null == apply) {
            return ServerResponse.createBySuccessMsg("Allocation data does not exist.");
        }
        apply.setMargin(apply.getMargin().add(amount));
        // 判断充值金额是否大于一次的管理费，如果大于修改状态未正常；否则状态不变
        AtomicReference<StAllocationSetting> setting = new AtomicReference<>(new StAllocationSetting());
        List<StAllocationSetting> settingList = stAllocationSettingMapper.selectList(null);
        settingList.forEach(set -> {
            // 前开后闭
            if (apply.getFundsAmount().compareTo(set.getLow()) > 0 && apply.getFundsAmount().compareTo(set.getHigh()) <= 0) {
                setting.set(set);
            }
        });
        BigDecimal manageFee = apply.getFundsAmount().multiply(setting.get().getRate());
        if (apply.getMargin().subtract(manageFee).compareTo(apply.getManageFee()) >= 0) {
            apply.setStatus(FundsApply.STATUS_1);
        }
        fundsApplyMapper.update(apply);

        // 修改用户可用余额
        user.setEnableAmt(enableAmt.subtract(amount));
        userMapper.updateById(user);

        // 增加保证金流水记录
        UserCashDetail ucd = new UserCashDetail();
        ucd.setPositionId(apply.getId());
        ucd.setAgentId(user.getAgentId());
        ucd.setAgentName(user.getAgentName());
        ucd.setUserId(user.getId());
        ucd.setUserName(user.getRealName());
        ucd.setDeType("Supplementary margin");
        ucd.setDeAmt(amount);
        ucd.setDeSummary("Apply for a day-by-day allocation:" + apply.getOrderNumber() + "，Supplementary margin：" + amount);
        ucd.setAddTime(new Date());
        ucd.setIsRead(Integer.valueOf(0));
        int insertSxfCount = this.userCashDetailMapper.insert(ucd);
        if (insertSxfCount > 0) {
            log.info("【补充保证金】成功");
        }
        return ServerResponse.createBySuccess();
    }

    @Override
    public int update(FundsApply model) {
        int ret = fundsApplyMapper.update(model);
        return ret>0 ? ret: 0;
    }

    /**
     * 配资申请-保存
     */
    @Override
    public ServerResponse save(FundsApply model) {
        int ret = 0;
        if(model!=null && model.getId()>0){
            ret = fundsApplyMapper.update(model);
        } else{
            ret = fundsApplyMapper.insert(model);
        }
        if(ret>0){
            return ServerResponse.createBySuccessMsg("Operation successfully");
        }
        return ServerResponse.createByErrorMsg("Operation failed");
    }

/**
 * 配资申请-审核
 */
@Transactional
public ServerResponse audit(FundsApply model, HttpServletRequest request) throws Exception {
        FundsApply fundsApply = this.fundsApplyMapper.load(model.getId().intValue());
        int ret = 0;

        if (model != null && model.getId().intValue() > 0) {
            User user = this.userMapper.selectByPrimaryKey(fundsApply.getUserId());

            if (model.getStatus().intValue() == 1) {
                 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                     String begtime = df.format(new Date()).split(" ")[0] + " 0:00:00";
                     Date date = DateTimeUtil.strToDate(begtime);
                     Date begDate = DateTimeUtil.addDay(date, 1);
                     model.setBeginTime(begDate);
//                 String endtime = df.format(new Date()).split(" ")[0] + " 23:59:59";
                 // 目前是用户自己取消 不设置结束时间了
//                 Date endDate = DateTimeUtil.strToDate(endtime);
//                 endDate = DateTimeUtil.addDay(endDate, model.getTradersCycle().intValue() + 1);
//                 model.setEndTime(endDate);

                 model.setEnabledTradingAmount(fundsApply.getTotalTradingAmount());
                 FundsSetting fundsSetting = this.iFundsSettingService.getFundsSetting();

                 BigDecimal lineUnwind = fundsApply.getMargin().multiply(fundsSetting.getDaysUnwind()).add(fundsApply.getFundsAmount()).setScale(2, 4);
                 model.setLineUnwind(lineUnwind);

                 BigDecimal lineWarning = fundsApply.getMargin().multiply(fundsSetting.getDaysWarning()).add(fundsApply.getFundsAmount()).setScale(2, 4);
                 model.setLineWarning(lineWarning);
               }

               model.setAuditTime(DateTimeUtil.getCurrentDate());
               ret = this.fundsApplyMapper.update(model);

               if (ret > 0) {
                // 可用现金
                 BigDecimal user_enable_amt = user.getEnableAmt();

                if (model.getStatus().intValue() == 1) {
                    // 总金额
                      BigDecimal user_all_amt = user.getUserAmt();
                      // 配资管理费
//                    BigDecimal manageFee = fundsApply.getManageFee();
                    // 总金额 减去 配资管理费
//                    BigDecimal reckon_all = user_all_amt.subtract(manageFee);
                    BigDecimal fundsAmount = fundsApply.getFundsAmount();
                    // 这里应该只把配资金额给到用户配资账户里 保证金不需要了  因为保证金也不能参与购买行为
                    BigDecimal tradingAmount = user.getTradingAmount().add(fundsAmount);
                      log.info("【配资审核通过】用户总资金  = {} , 可用资金 = {} , 总操盘资金 = {}", new Object[] { user_all_amt, user_enable_amt, tradingAmount });
//                      user.setUserAmt(reckon_all);
                      user.setTradingAmount(tradingAmount);
                      int updateUserCount = this.userMapper.updateByPrimaryKeySelective(user);

                      if (updateUserCount > 0) {
                          log.info("【配资审核通过】修改用户金额成功");

                        FundsTradingAccount fundsTradingAccount = this.fundsTradingAccountMapper.getAccountByNumber(model.getSubaccountNumber());
                        if (fundsTradingAccount != null) {
                            // 将子账户设置为再用
                          fundsTradingAccount.setStatus(Integer.valueOf(1));
                          this.fundsTradingAccountMapper.update(fundsTradingAccount);
                        }

                        // 配资记录
                        UserCashDetail ucd = new UserCashDetail();
                        ucd.setPositionId(fundsApply.getId());
                        ucd.setAgentId(user.getAgentId());
                        ucd.setAgentName(user.getAgentName());
                        ucd.setUserId(user.getId());
                        ucd.setUserName(user.getRealName());
                        ucd.setDeType("The allocation has been approved.");
                        ucd.setDeAmt(fundsApply.getPayAmount());
                        ucd.setDeSummary("Apply for a day-by-day allocation:"
                                + fundsApply.getOrderNumber()
                                + "，The capital allocation has been approved, and the deposit will be unfrozen to the capital allocation account.："
                                + fundsApply.getPayAmount());
                        ucd.setAddTime(new Date());
                        ucd.setIsRead(Integer.valueOf(0));
                        int insertSxfCount = this.userCashDetailMapper.insert(ucd);

                        if (insertSxfCount > 0) {
                              log.info("【配资审核通过】申请成功");
                            }
                              } else {
                                log.error("【配资审核通过】修改用户金额出错");
                                throw new Exception("[Passed the allocation review] There is an error in modifying the user amount");
                              }

                        } else {
                        // 审核失败 需要回退可用现金
                          BigDecimal reckon_enable = user_enable_amt.add(fundsApply.getPayAmount());
                          user.setEnableAmt(reckon_enable);
                          int updateUserCount = this.userMapper.updateByPrimaryKeySelective(user);
                          if (updateUserCount > 0) {
                                log.info("【配资审核未通过】修改用户金额成功");
                                UserCashDetail ucd = new UserCashDetail();
                                ucd.setPositionId(fundsApply.getId());
                                ucd.setAgentId(user.getAgentId());
                                ucd.setAgentName(user.getAgentName());
                                ucd.setUserId(user.getId());
                                ucd.setUserName(user.getRealName());
                                ucd.setDeType("Allocation Review Failed");
                                ucd.setDeAmt(fundsApply.getPayAmount());
                                ucd.setDeSummary("Apply for a day-by-day allocation:"
                                        + fundsApply.getOrderNumber()
                                        + "，The allocation review failed, and the deposit was unfrozen to the balance.："
                                        + fundsApply.getPayAmount() + "，原因：" + model.getAuditOpinion());
                                ucd.setAddTime(new Date());
                                ucd.setIsRead(Integer.valueOf(0));
                                int insertSxfCount = this.userCashDetailMapper.insert(ucd);
                                if (insertSxfCount > 0) {
                                      log.info("【按天配资】申请成功");
                                }
                              } else {
                                log.error("【按天配资】修改用户金额出错");
                                throw new Exception("[Allotment by day] Error in modifying the user amount");
                              }
                                        }

                                     log.info("配资申请-审核 = {}  实际购买金额 =  {} 比较结果 = {} ", Integer.valueOf(0));
                                }
                           }
                            if (ret > 0) {
                                   return ServerResponse.createBySuccessMsg("Operation successfully");
                            }
                        return ServerResponse.createByErrorMsg("Operation failed");
}


    /*配资申请-查询列表*/
    @Override
    public ServerResponse<PageInfo> getList(int pageNum, int pageSize, String orderNumber,
                                            String userPhone, Integer status, HttpServletRequest request){
        Page<Object> page = PageHelper.startPage(pageNum, pageSize);

        ArrayList<FundsApplyVo> fundsApplyVos = new ArrayList<>();
        List<FundsApply> listData = this.fundsApplyMapper.pageList(pageNum, pageSize, orderNumber, userPhone, status);
        for (FundsApply fundsApply : listData) {
            FundsApplyVo fundsApplyVo = new FundsApplyVo();
            BeanUtils.copyProperties(fundsApply, fundsApplyVo);

            // 计算滞纳金
            BigDecimal fundsAmount = fundsApply.getFundsAmount();
            Date endTime = fundsApply.getEndTime();

            BigDecimal lateFees = new BigDecimal(BigInteger.ZERO);
            // 计算与当前日期相差多少天
            if (null != endTime) {
                long betweenDay = DateUtil.between(endTime, DateUtil.date(), DateUnit.DAY, false);
                if (betweenDay > 0) {
                    lateFees = fundsAmount.multiply(new BigDecimal(betweenDay)).multiply(new BigDecimal("0.02"));
                }
            }

            fundsApplyVo.setLateFees(lateFees);
            fundsApplyVos.add(fundsApplyVo);
        }


        PageInfo pageInfo = new PageInfo(page);
        pageInfo.setList(fundsApplyVos);
        return ServerResponse.createBySuccess(pageInfo);
    }


    /*配资申请-查询详情*/
    @Override
    public ServerResponse getDetail(int id) {
        return ServerResponse.createBySuccess(this.fundsApplyMapper.load(id));
    }

    /**
     * 配资申请-用户配资列表
     */
    @Override
    public ServerResponse<PageInfo> getUserApplyList(int pageNum, int pageSize, HttpServletRequest request){
        User user = this.iUserService.getCurrentRefreshUser(request);
        if (user == null){
            return ServerResponse.createBySuccessMsg("Please log in first.");
        }
        PageHelper.startPage(pageNum, pageSize);
        List<FundsApply> listData = this.fundsApplyMapper.getUserApplyList(pageNum, pageSize, user.getId());
        listData.forEach(fundsApply -> {
            BigDecimal margin = fundsApply.getMargin();
            BigDecimal manageFee = fundsApply.getManageFee();
            if (null != margin && null != manageFee) {
                fundsApply.setResidueMargin(fundsApply.getMargin().subtract(fundsApply.getManageFee()));
            }else {
                fundsApply.setResidueMargin(BigDecimal.ZERO);
            }
        });
        PageInfo pageInfo = new PageInfo(listData);
        pageInfo.setList(listData);
        return ServerResponse.createBySuccess(pageInfo);
    }

    /**
     * 配资申请-用户操盘中子账户
     */
    @Override
    public ServerResponse<PageInfo> getUserEnabledSubaccount(HttpServletRequest request){
        User user = this.iUserService.getCurrentRefreshUser(request);
        List<FundsApply> listData = this.fundsApplyMapper.getUserEnabledSubaccount(user.getId());
        PageInfo pageInfo = new PageInfo();
        pageInfo.setList(listData);
        return ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    @Transactional
    public ServerResponse cancelFundsApply(Integer fundApplyId, HttpServletRequest request) {
        User user = this.iUserService.getCurrentRefreshUser(request);
        if (user == null){
            return ServerResponse.createBySuccessMsg("Please log in first.");
        }

        // 查询配置记录
        FundsApply fundsApply = fundsApplyMapper.load(fundApplyId);
        if (null == fundsApply) {
            return ServerResponse.createByErrorMsg("The allocation record does not exist.");
        }

        Integer fundsUserId = fundsApply.getUserId();
        if (!fundsUserId.equals(user.getId())) {
            return ServerResponse.createByErrorMsg("The current allocation record is not what you applied for and cannot be cancelled.!");
        }

        // 判断配资记录状态 如果是保证金不足，不能进行取消
        Integer status = fundsApply.getStatus();
        if (FundsApply.STATUS_6.equals(status)) {
            return ServerResponse.createByErrorMsg("The deposit is insufficient and cannot be cancelled. Please supplement the deposit.");
        }

        // 如果不是操盘中  可以直接设置为取消；
        if (FundsApply.STATUS_1.equals(status)) {
            // 从配资账户 扣除用户的配资的 配资金额(fundsAmount)
            BigDecimal fundsAmount = fundsApply.getFundsAmount();

            // 操盘中能取消的前提是自己的可用资金可以填补借款
            BigDecimal tradingAmount = user.getTradingAmount();
            tradingAmount = tradingAmount.subtract(fundsAmount);

            // 如果差值小于0，则说明配资金额不够了
            if (tradingAmount.compareTo(BigDecimal.ZERO) < 0) {
                return ServerResponse.createByErrorMsg("Your allocation balance is insufficient and cannot be cancelled!　");
            }

            // 保证金返还到可用金额
            BigDecimal margin = fundsApply.getMargin(); // 保证金
            BigDecimal manageFee = fundsApply.getManageFee(); // 管理费
            BigDecimal residueMargin = margin.subtract(manageFee); // 剩余管理费
            BigDecimal enableAmt = user.getEnableAmt();
            enableAmt = enableAmt.add(residueMargin);

            User updateUser = new User();
            updateUser.setId(user.getId());
            updateUser.setEnableAmt(enableAmt);
            updateUser.setTradingAmount(tradingAmount);
            userMapper.updateByPrimaryKeySelective(updateUser);
        }

        FundsApply updateApply = new FundsApply();
        updateApply.setId(fundsApply.getId());
        updateApply.setStatus(FundsApply.STATUS_5);
        fundsApplyMapper.update(updateApply);
        return ServerResponse.createBySuccessMsg("Canceled successfully!");
    }
    @Override
    @Transactional
    public ServerResponse cancelFundsApplyAdmin(Integer fundApplyId, HttpServletRequest request) {

        // 查询配置记录
        FundsApply fundsApply = fundsApplyMapper.load(fundApplyId);
        if (null == fundsApply) {
            return ServerResponse.createByErrorMsg("The allocation record does not exist.");
        }

        Integer userId = fundsApply.getUserId();
        User user = userMapper.selectById(userId);
        if (null == user) {
            return ServerResponse.createByErrorMsg("The user record does not exist.");
        }


        // 判断配资记录状态 如果是保证金不足，不能进行取消
        Integer status = fundsApply.getStatus();
        if (FundsApply.STATUS_6.equals(status)) {
            return ServerResponse.createByErrorMsg("The deposit is insufficient and cannot be cancelled. Please supplement the deposit.");
        }

        // 如果不是操盘中  可以直接设置为取消；
        if (FundsApply.STATUS_1.equals(status)) {
            // 从配资账户 扣除用户的配资的 配资金额(fundsAmount)
            BigDecimal fundsAmount = fundsApply.getFundsAmount();

            // 操盘中能取消的前提是自己的可用资金可以填补借款
            BigDecimal tradingAmount = user.getTradingAmount();
            tradingAmount = tradingAmount.subtract(fundsAmount);

            // 如果差值小于0，则说明配资金额不够了
            if (tradingAmount.compareTo(BigDecimal.ZERO) < 0) {
                return ServerResponse.createByErrorMsg("Your allocation balance is insufficient and cannot be cancelled!　");
            }

            // 保证金返还到可用金额
            BigDecimal margin = fundsApply.getMargin();
            BigDecimal enableAmt = user.getEnableAmt();
            enableAmt = enableAmt.add(margin);

            User updateUser = new User();
            updateUser.setId(user.getId());
            updateUser.setEnableAmt(enableAmt);
            updateUser.setTradingAmount(tradingAmount);
            userMapper.updateByPrimaryKeySelective(updateUser);
        }

        FundsApply updateApply = new FundsApply();
        updateApply.setId(fundsApply.getId());
        updateApply.setStatus(FundsApply.STATUS_5);
        fundsApplyMapper.update(updateApply);
        return ServerResponse.createBySuccessMsg("Canceled successfully!");
    }

    @Override
    public ServerResponse getAgentList(int pageNum, int pageSize, String orderNumber, String userPhone, Integer status, HttpServletRequest request) {
        String loginToken = CookieUtils.readLoginToken(request, PropertiesUtil.getProperty("agent.cookie.name"));
        String agentJson = RedisShardedPoolUtils.get(loginToken);
        AgentUser agentUser = (AgentUser) JsonUtil.string2Obj(agentJson, AgentUser.class);
        if (agentUser==null){
            return ServerResponse.createByErrorMsg("Failed to get proxy information");
        }

        // 代理的userId
        Integer agentUserId = agentUser.getId();

        // 查询该代理下所有的用户的配资列表
        Page<Object> page = PageHelper.startPage(pageNum, pageSize);
        List<FundsApply> listData = this.fundsApplyMapper.getAgentList(pageNum, pageSize, orderNumber, userPhone, status, agentUserId);
        ArrayList<FundsApplyVo> fundsApplyVos = new ArrayList<>();
        for (FundsApply fundsApply : listData) {
            FundsApplyVo fundsApplyVo = new FundsApplyVo();
            BeanUtils.copyProperties(fundsApply, fundsApplyVo);

            // 计算滞纳金
            BigDecimal fundsAmount = fundsApply.getFundsAmount();
            Date endTime = fundsApply.getEndTime();

            BigDecimal lateFees = new BigDecimal(BigInteger.ZERO);
            // 计算与当前日期相差多少天
            if (null != endTime) {
                long betweenDay = DateUtil.between(endTime, DateUtil.date(), DateUnit.DAY, false);
                if (betweenDay > 0) {
                    lateFees = fundsAmount.multiply(new BigDecimal(betweenDay)).multiply(new BigDecimal("0.02"));
                }
            }

            fundsApplyVo.setLateFees(lateFees);
            fundsApplyVos.add(fundsApplyVo);
        }

        PageInfo pageInfo = new PageInfo(page);
        pageInfo.setList(listData);
        return ServerResponse.createBySuccess(pageInfo);
    }



}
